<template>
  <div class="mini-sensor-chart">
    <canvas
      v-if="chartData.labels && chartData.labels.length > 0"
      :id="`miniChartCanvas-${sensorId}`"
    ></canvas>
    <div v-else style="text-align: center; color: #aaa">加载中...</div>
    <p v-if="chartError" class="chart-error">{{ chartError }}</p>
    <p v-if="chartLoading" class="chart-loading">数据加载中...</p>
    <p
      v-if="!chartLoading && !chartError && (!chartData.labels || chartData.labels.length === 0)"
      class="chart-no-data"
    >
      暂无数据
    </p>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, onUnmounted, nextTick } from 'vue'
import Chart from 'chart.js/auto' // 确保正确导入 Chart.js

const props = defineProps({
  sensorId: {
    // 传感器ID，如 FIC1001, FI615
    type: String,
    required: true,
  },
  deviceName: {
    // 装置名称，如 联醇装置, 解吸浓缩系统装置
    type: String,
    required: true,
  },
})

const chartInstance = ref(null)
const chartLoading = ref(false)
const chartError = ref(null)
const chartData = ref({ labels: [], data: [] }) // 存储从后端获取的数据

/**
 * 销毁 Chart.js 实例。
 * === 将此函数定义移动到 fetchAndDrawChart 之前 ===
 */
const destroyChart = () => {
  if (chartInstance.value) {
    chartInstance.value.destroy()
    chartInstance.value = null
    console.log(`MiniSensorChart: Chart instance for ${props.sensorId} destroyed.`)
  }
}

/**
 * 生成模拟的迷你图表数据（作为后端请求失败的 fallback）。
 * @param {string} sensorId - 传感器ID。
 * @param {number} numPoints - 数据点数量。
 * @returns {Object} 包含 labels 和 data 的模拟数据。
 */
const generateMockMiniChartData = (sensorId, numPoints = 20) => {
  const labels = []
  const data = []
  let baseValue
  let fluctuationRange

  if (sensorId.includes('FIC')) {
    baseValue = 50
    fluctuationRange = 10
  } else if (sensorId.includes('TE')) {
    baseValue = 25
    fluctuationRange = 5
  } else if (sensorId.includes('PIC')) {
    baseValue = 100
    fluctuationRange = 15
  } else if (sensorId.includes('LI')) {
    baseValue = 70
    fluctuationRange = 8
  } else if (sensorId.includes('FI')) {
    baseValue = 60
    fluctuationRange = 10
  } else {
    baseValue = 40
    fluctuationRange = 12
  }

  let currentValue = baseValue + (Math.random() - 0.5) * fluctuationRange

  for (let i = 0; i < numPoints; i++) {
    const date = new Date(Date.now() - (numPoints - 1 - i) * 5 * 1000)
    labels.push(date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }))
    currentValue += (Math.random() - 0.5) * (fluctuationRange / 3)
    currentValue = Math.max(
      baseValue - fluctuationRange,
      Math.min(baseValue + fluctuationRange, currentValue),
    )
    data.push(parseFloat(currentValue.toFixed(2)))
  }
  return { labels, data }
}

/**
 * 获取迷你图表数据并绘制。
 */
const fetchAndDrawChart = async () => {
  chartLoading.value = true
  chartError.value = null
  chartData.value = { labels: [], data: [] } // 清空旧数据
  destroyChart() // <-- 这里调用 destroyChart，确保它在调用前已定义

  try {
    console.log(
      `MiniSensorChart: Fetching data for point: ${props.sensorId} via /api/get_latest_point_data.`,
    )
    const response = await fetch(`/api/get_latest_point_data?point=${props.sensorId}`)

    if (!response.ok) {
      const errorText = await response.text()
      throw new Error(`HTTP error! status: ${response.status} - ${errorText}`)
    }
    const result = await response.json()

    if (!result.success || !result.data || !Array.isArray(result.data)) {
      throw new Error(`API returned invalid data or success: false.`)
    }

    chartData.value = {
      labels: result.data.map((item) =>
        new Date(item.datetime).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }),
      ),
      data: result.data.map((item) => item.value),
    }
    console.log(`MiniSensorChart: Data loaded for ${props.sensorId}.`)
  } catch (error) {
    console.error(
      `MiniSensorChart: Error fetching data for ${props.sensorId} from backend, using mock data:`,
      error,
    )
    chartError.value = `数据加载失败。`
    chartData.value = generateMockMiniChartData(props.sensorId) // 使用模拟数据作为 fallback
    console.log(`MiniSensorChart: Using mock data for ${props.sensorId}.`)
  } finally {
    chartLoading.value = false
    await nextTick() // 确保DOM更新，以便Canvas可以被正确获取和绘制
    drawChart() // 绘制或更新图表
  }
}

/**
 * 绘制或更新 Chart.js 图表。
 */
const drawChart = () => {
  const canvasId = `miniChartCanvas-${props.sensorId}`
  const canvas = document.getElementById(canvasId)

  if (!canvas) {
    console.warn(`MiniSensorChart: Canvas element ${canvasId} not found for drawing.`)
    return
  }
  const ctx = canvas.getContext('2d')
  if (!ctx) {
    console.error(`MiniSensorChart: Could not get 2D context for ${canvasId}.`)
    return
  }

  // 因为 fetchAndDrawChart 已经调用了 destroyChart，这里不再需要额外的销毁逻辑。
  // 确保 chartInstance.value 是 null，这样 Chart.js 总是创建一个新的。
  if (chartInstance.value) {
    // 理论上这里不应该有实例了，以防万一
    chartInstance.value.destroy()
  }

  if (!chartData.value.labels || chartData.value.labels.length === 0) {
    // 清空 canvas 并不绘制图表，让模板中的 v-else 文本显示
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    return
  }

  chartInstance.value = new Chart(ctx, {
    type: 'line',
    data: {
      labels: chartData.value.labels,
      datasets: [
        {
          label: props.sensorId,
          data: chartData.value.data,
          borderColor: '#3f51b5', // 主要传感器的图表颜色
          backgroundColor: 'rgba(63, 81, 181, 0.1)',
          borderWidth: 1.5,
          tension: 0.3,
          pointRadius: 0,
          fill: false,
        },
      ],
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: { display: false },
        title: {
          display: true,
          text: props.sensorId, // 显示传感器ID作为图表标题
          font: { size: 12 },
          color: '#333',
        },
      },
      scales: {
        x: {
          display: false, // 隐藏X轴，保持简洁
          ticks: { maxTicksLimit: 3 },
        },
        y: {
          display: false, // 隐藏Y轴
          beginAtZero: false, // 不强制从0开始
        },
      },
      animation: {
        duration: 0, // 关闭动画，避免快速切换时的视觉延迟
      },
    },
  })
}

onMounted(() => {
  fetchAndDrawChart()
})

// 监听 sensorId 或 deviceName 变化时重新获取并绘制
watch(
  () => [props.sensorId, props.deviceName],
  () => {
    fetchAndDrawChart()
  },
)

// 组件卸载时销毁图表实例
onUnmounted(() => {
  destroyChart()
})
</script>

<style scoped>
.mini-sensor-chart {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  position: relative;
}

.mini-sensor-chart canvas {
  width: 100% !important;
  height: calc(100% - 20px) !important; /* 留出一点空间给标题 */
  max-height: 120px; /* 限制 Canvas 实际高度 */
}

.chart-error,
.chart-loading,
.chart-no-data {
  position: absolute;
  font-size: 0.8em;
  color: #999;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  width: 100%;
}
.chart-error {
  color: #dc3545;
}
.chart-loading {
  color: #007bff;
}
</style>
